package client_tests;

import net.es.lookup.client.QueryClient;
import net.es.lookup.client.SimpleLS;
import net.es.lookup.common.exception.LSClientException;

/**
 * Created with IntelliJ IDEA.
 * User: luke
 * Date: 10/2/13
 * Time: 6:07 PM
 * To change this template use File | Settings | File Templates.
 */
public class MultipleRegistrations implements ScalabilityTest {

    private ResultTransmitter rx;
    private SimpleLS sls;
    private QueryClient qc;
    private String targetHost;
    private int port;
    private String sourceHost;
    private int op_interval;
    private MultipleRegistrationThread[] regThreads;
    private int numThreads;
    private int testRounds;

    private static volatile boolean shutdown = false;
    private static int pending;

    @Override
    public void initialize(String targetHost, int port, String sourceHost, int op_interval, int numThreads, int testRounds) throws LSClientException {

        rx = new ResultTransmitter();
        sls = new SimpleLS(targetHost, port);
        this.sourceHost = sourceHost;
        this.targetHost = targetHost;
        this.port = port;
        this.op_interval = op_interval;
        this.numThreads = numThreads;
        this.testRounds = testRounds;
        regThreads = new MultipleRegistrationThread[numThreads];

        for (int i = 0; i < numThreads; i++) {

            regThreads[i] = new MultipleRegistrationThread(sourceHost, targetHost, port, i, op_interval, testRounds);
        }
    }

    @Override
    public void runTest() throws LSClientException {

        int i;
        pending = numThreads * testRounds;
        for (i = 0; i < numThreads; i++) {

            regThreads[i].start();
        }

        //TODO: implement barrier

        //TODO: wait on pending variable or timeout
        while (!shutdown && getPending() > 0) {

            synchronized (MultipleRegistrations.class) {

                try {

                    System.out.println(MultipleRegistrations.class + " waiting for threads to finish work");
                    MultipleRegistrations.class.wait(5000);

                } catch (InterruptedException e) {
                    System.out.println("Main thread interrupted while waiting on client threads");
                    e.printStackTrace();
                }
            }
        }

        for (i = 0; i < numThreads; i++) {

            regThreads[i].printResults(rx);

            try {

                regThreads[i].join();
            } catch (InterruptedException ignored) { }
        }
    }

    public static synchronized int getPending() {

        return pending;
    }

    public static synchronized void decrementPending() {

        if (--pending == 0) {

            setShutdownFlag(true);
        }
    }

    public static synchronized void setShutdownFlag(boolean value) {

        shutdown = value;
    }

    @Override
    public void printResults() {

        rx.print();
    }
}
